If this is a first time you visiting Scrolls, please register in Fight Club. If you already registered, please authorize on Fight Club start page with your login and password.
Alex Nomad Начинающим клановым программистам. Часть III.
В свете последних событий с взломами клансайтов настало время поговорить о безопасности клановых сервисов. К сожалению, я не являюсь специалистом по информационной безопасности, поэтому рассуждения буду вести исключительно исходя из собственного опыта. В этой статье я затрону исключительно вопросы противодействие взлому клановых сервисов.
Как правило, хакеры действуют в следующей последовательности: 1. Сбор информации о сайте 2. Проникновение (взлом) сайта Разберем способы противодействия, затрудняющие выполнение намерений хакера. Хочу заметить, что разработать исключительно надежные средства защиты от хакера практически невозможно. Но вот затруднить ему свое черное дело мы просто обязаны. Начнем с конца.
Противодействие взлому сайта Как правило, наиболее опасные дыры во многих PHP-скриптах возникают из-за кода, написанного без учета соответствующих требований безопасности. В приложение злонамеренные данные могут попасть в основном через загрузку методами GET, POST и FILE. То есть любая форма, расположенная на сайте потенциально опасна, будь то сложная форма заполнения персональной информации или простой ввод логина и пароля. Обе эти формы несут одинаковую опасность для вашего сайта. Следует понимать, что хакер может ввести данные, которые кардинально отличаются от ваших ожиданий и предположений. Вы должны тщательно проверять все данные, передаваемые веб-браузером.
Для начала надо перевести ваш PHP в более безопасный режим, для этого необходимо отключить в настройках PHP переменную register_globals, т.е. установить register_globals=OFF. В случае, если значение параметра register_globals установлено в ON, перед выполнением вашего кода будут инициализированы различные переменные, например, переменные, переданные при отправке формы. Например, при вызове скрипта http://www.mysite.ru/myscript.php?city=capitalcity будет проинициализирована переменная $city – ей будет присвоено значение «capitalcity». Учитывая тот факт, что PHP не требует обязательной инициализации переменных, написать потенциально опасный код очень легко.
Проверьте работу этого кода при вызове http://www.mysite.ru/myscript.php?authorized=1 ......if (authenticated_user()) { ............$authorized = true; ......} ......//..... ......if ($authorized) { ............include "/highly/sensitive/data.php"; ......} ......Пример взят из справочника PHP
Перевод параметра register_globals в значение OFF приведет к отключению автоматической инициализации переменных. В этом случае все данные необходимо будет получать через суперглобальные переменные $_GET, $_POST и $_FILE, например вот так $_GET[‘city’]. Это менее удобно, но более надежно.
Если по каким либо причинам вы не можете установить параметр register_globals в значение OFF, то можно сделать небольшой трюк, который позволит вам добиться примерно такого же результата независимо от значения настройки register_globals. Для этого в ваш единый заголовочный файл вставьте вот такой код. ......$input_data_arr = array('_GET', '_POST'); ......foreach($input_data_arr as $input_data) ............foreach($$input_data as $paramname=>$paramvalue) ..................unset($$paramname);
Следующим этапом защиты наших скриптов является надежная проверка вводимых данных. Для этого я использую простейшую проверку специально спроектированными функциями. ......$city = get_input_data_city(‘city’, ‘capitalcity’, …); ......$num = get_input_data_int(‘num, 0, …); ......$nick = get_input_data_string(‘city’, 0, ‘ а-яa-z0-9_\-’);
Действие этих функций достаточно простое: ......function get_input_data_int ($varname, $default=0){ ............if(isset($_GET[$varname])) return intval(round($_GET[$varname],0)); ............if(isset($_POST[$varname])) return intval(round($_POST[$varname],0)); ............return NULL; ......}
Наиболее частым способом внедрения на сайт является использование SQL-инъекций. Большинство сервисов используется для своей работы базы данных, например mySql. А это значит в коде скрипта есть обращение к базе данных, например вот такое: ......$sql="SELECT nick, klan FROM nickstable WHERE nick='$input_nick'"; ......$result = mysql_query($sql); Попробуйте проверить, что будет делать этот скрипт, если его запустить с параметром input_nick равным « UNION SELECT name, password FROM usersrights». Надежная проверка входных данных на допустимые символы легко отсечет такое внедрение.
Еще одним способом внедрения является загрузка файлов на сайт, например картинок. Здесь алгоритм рекомендуемых действий примерно такой: 1. Проверьте, что файл с картинкой действительно является картинкой. 2. Измените размер картинки. В случае удачи это гарантирует, что загружена именно картинка, а не какой-то скрипт или троян.
Противодействие сбору сведений о сайте Теперь понятно, почему надо тщательно проверять все вводимые данные. Но у вас может возникнуть вполне разумный вопрос, а как хакер узнает какие переменные я использую? Поверьте это несложно. Во-первых, зная контекст решаемой задачи нетрудно догадаться. Во-вторых на большинстве сайтов достаточно ввести неправильные данные, для того, чтобы получить исчерпывающий список ошибок с перечислением имен переменных, участвующих в ошибке, например: Notice: Undefined variable: city2 in /home/www/myscript.php on line 11
Необходимо добиться правильного использования функции error_reporting(). Во время отладки и только для разработчика эта функция должна показывать полный список ошибок. Для всех остальных – ни каких ошибок! Для начала можно просто привязать к IP разработчика или каким-то хитрым куки, имеющихся только у него, например в общий заголовочный файл можно поместить вот такую конструкцию: ......if($_SERVER['REMOTE_ADDR']==’12.34.45.56’) error_reporting(E_ALL); ......else error_reporting(E_NONE);
В этой небольшой статье я затронул лишь крохотную часть методов и принципов защиты сайтов от взлома. Я надеюсь, что приведенные примеры и разъяснения найдут применение при реализации БКшных клановых сервисов и число взломов хоть немного снизится.
Для занесения данных в sql рекомендую всегда обрабатывать данные функцией mysql_escape_string(), а для данных предназначенных для последующего вывода на страницы вот простая функция: ------ function no_tags($Str){ $search=array( "<", ">", "\\","\r\n","\n", "\r", '"', "'"); $replace=array("<",">","/","<br>", "<br>","<br>",""","’");
return str_replace($search, $replace, $Str); } ------ После обработки ею данные из формы можно смеро пихать в хтмл, они уже не повредят.
Алексей, помоги пожалуйста разобарться с загрузкой фйлов на сервер) никак не могу подобрать второй параметр для функции move_uploaded_file($_FILES["myfile"]["tmp_name"], "???") какой путь там указывать? допустим адрес скрипта на http://site.ru/upload.php а файл нужно поместить в папку http://site.ru/files/ то пишет что нет такой папки, то права не позволяют(хотя 777), то возвращает, что все ок, но самого файла нет. нигде так и не нашел понятного примера использования этой функции:(
Эта функция проверяет, является ли файл filename загруженным на сервер (переданным по протоколу HTTP POST). Если файл действительно загружен на сервер, он будет перемещён в место, указанное в аргументе destination.
путь к папке от рута пиши, т.е. напр /home/www/ и т.д.
Гость БК
11-10-07 @ 13:32
> ......$sql="SELECT nick, klan FROM nickstable WHETE nick=$input_nick"; > ......$result = mysql_query($sql); > Попробуйте проверить, что будет делать этот скрипт, если > его запустить с параметром input_nick равным « UNION SELECT > name, password FROM usersrights». Надежная проверка входных > данных на допустимые символы легко отсечет такое внедрение. >
да хоть как фильтруй все равно здесь чистый SQLInj. Здесь обязательно - 1. параметр условия брать в кавычки ( ' ) ибо просто из-за ника с пробелом получится SQL Error 2. и естественно фильтр переменной на кавычки, напр addslashes т.е. $input_nick = addslashes ( $input_nick ); $sql="SELECT nick, klan FROM nickstable WHERE nick='$input_nick'"; $result = mysql_query($sql);
Совершенно верно, все строковые величины по любому должны быть в кавычках, а наличие кавычек в самой строке лечится ф-цией mysql_escape_string(). А еще лучше вообще скобки и кавычки из данных вырезать или заменять на что-то безопасное.
Да, спасибо за замечание про кавычки в примере. Исправил.
По поводу фильтра для переменных. Моя идея была немного другой. Я заменяю все входящие через GET и POST строки, в том числе заменяю кавычки, угловые скобки, а также знаки равно и слова jаvаscript с аналогами на аналогичные html-сущности. А потом уже не парюсь, что у меня может быть SQLinj
Гость БК
11-10-07 @ 15:20
Re: Re:
Очень часто бывает, что нельзя изменять текст. Напр. управление контентом сайта подраземевает сохранение кавычек и тегов в неизменном виде. ЗЫ. по-моему необратимое изменение данных - зло )
Гость БК
11-10-07 @ 18:15
Re: Re: Re:
Замена символов на их html-сущности - всегда обратимое изменение. Но когда ты делаешь возврат - это всегда осознано. В остальных случаях можно не беспокоится что вылезет бяка )))
> Еще одним способом внедрения является загрузка файлов на > сайт, например картинок. Здесь алгоритм рекомендуемых действий > примерно такой: > 1. Проверьте, что файл с картинкой действительно является > картинкой. > 2. Измените размер картинки. В случае удачи это гарантирует, > что загружена именно картинка, а не какой-то скрипт или > троян.
Был у меня случай, когда я проверял валидность картинки, а вот о расширении забыл. Человек дописал в конец JPGа свой скрипт и переименовал в .php, в результате проверка картинки прокатила, файл сохранился, а вот интерпретатор пхп c удовольствием его съел, пропустив все графические данные и дойдя до "<?" - как результат скрипт был исполнен. Благо это был знакомый прогер и ничего мерзопакостного там не было. Так что проверяйте не только данные, но и расширение. Что касается изменения размера и сохранения результата - мера довольно жестокая, даже если размер меняется сам на себя, сжатие JPG все равно подпортит качество и будет затрачено время на масштабирование и сжатие. Но если это некритично - метод хороший.
Гость БК
11-10-07 @ 15:24
Re:
на работе скриптиг для загрузки файлов написали - так он все файлы, будь то картинки или че, парсит и проверяет на вхождения потенциально опасных символов типа <?, #!/bin/perl и т.д., вроде пока осечек не было )
Гость БК
11-10-07 @ 18:14
Re: Re:
Если на отдельные символы - то непредставляю как работает. Ведь легко в какой-то картинке может возникнуть знак вопроса или кавычка....
Гость БК
11-10-07 @ 23:57
эскейпить данные разумнее до вывода а не после ввода. вместо mysql_escape_string нужно использовать mysql_real_escape_string, т.к. первая работает без учета текущей кодировки соединения с БД. а addslashes и вовсе не способна нормально защитить от SQL-иньекций
и тема XSS атак почти не раскрыта, а между тем они могут быть не менее опасны чем иньекции SQL-кода